#pragma once

#include "../USISlave.h"

using namespace System;
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;


namespace USI 
{
	public enum class _ExploreType
	{
		Any,
		Directories,
		Databases,
		Lists
	};

	public ref class ExplorerForm : public System::Windows::Forms::Form
	{
	private:
		_ExploreType ^_type;
	private: System::Windows::Forms::ImageList^  smallImageList;
	private: System::Windows::Forms::TextBox^  saveBox;
	private: System::Windows::Forms::ComboBox^  pathBox;


			 USISlave ^_slave;

		bool bIncludeFile(String ^path)
		{
			if (ExploreType->Equals(_ExploreType::Any))
				return true;

			if (ExploreType->Equals(_ExploreType::Databases))
			{
				return System::IO::Path::GetExtension(path)->Equals(".db");
			}

			if (ExploreType->Equals(_ExploreType::Lists))
			{
				return System::IO::Path::GetExtension(path)->Equals(".list");
			}

			return true;
		}

		System::Void GoToFolder(String ^pathToGo)
		{
			filesView->Items->Clear();
			String ^path = _slave->GetFullPath(pathToGo);
			pathBox->Text = path;
			
			ListView::ListViewItemCollection ^ collection = gcnew ListView::ListViewItemCollection(filesView);

			array<DirectoryInfo ^> ^directories = _slave->GetDirectories(path + System::IO::Path::DirectorySeparatorChar);
			int dirCount = directories->Length;
			for (int iDir = 0; iDir < dirCount; iDir++)
			{
				ListViewItem ^newItem = gcnew ListViewItem(directories[iDir]->Name);
				newItem->ImageIndex = 0;
				collection->Add(newItem);
			}

			if (!ExploreType->Equals(_ExploreType::Directories))
			{
				array<FileInfo ^> ^files = _slave->GetFiles(path + System::IO::Path::DirectorySeparatorChar);
				int filesCount = files->Length;
				for (int iFile = 0; iFile < filesCount; iFile++)
				{
					if (bIncludeFile(files[iFile]->Name))
					{
						ListViewItem ^newItem = gcnew ListViewItem(files[iFile]->Name);
						newItem->ImageIndex = 1;
						collection->Add(newItem);
					}
				}
			}
		}

	public:
		property String ^Path
		{
			String ^get()
			{
				return pathBox->Text;
			}

			System::Void set(String ^value)
			{
				GoToFolder(value);
			}
		}

		property _ExploreType ^ExploreType
		{
			_ExploreType ^get()
			{
				return _type;
			}

			System::Void set(_ExploreType ^value)
			{
				_type = value;
			}
		}

		property array<String ^> ^Files
		{
			array<String ^> ^get()
			{
				int count = filesView->SelectedItems->Count;
				array<String ^> ^list = gcnew array<String ^>(count);

				for (int iPath = 0; iPath < count; iPath++)
				{
					if (Path->Length > 0 && Path[Path->Length - 1] == '\\')
						list[iPath] = Path + filesView->SelectedItems[iPath]->Text;
					else
						list[iPath] = Path + System::IO::Path::DirectorySeparatorChar + filesView->SelectedItems[iPath]->Text;
				}

				return list;
			}
		}

		property String ^SaveFile
		{
			String ^get()
			{
				if (Path->Length > 0 && Path[Path->Length - 1] == '\\')
					return Path + saveBox->Text;
				else
					return Path + System::IO::Path::DirectorySeparatorChar + saveBox->Text;
			}
		}

		System::Void FillPathBox()
		{
			pathBox->Items->Clear();
			array<DriveInfo ^> ^drives = DriveInfo::GetDrives();

			for (int iDrive = 0; iDrive < drives->Length; iDrive++)
			{
				if (drives[iDrive]->DriveType.Equals(DriveType::Fixed))
				{
					pathBox->Items->Add(drives[iDrive]->RootDirectory);
				}
			}
		}

		ExplorerForm(USISlave ^slave, _ExploreType ^type, String ^path)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//

			saveBox->Visible = false;

			_slave = slave;
			ExploreType = type;

			FillPathBox();
			GoToFolder(path);
		}

		ExplorerForm(USISlave ^slave, _ExploreType ^type, String ^path, bool save)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//

			saveBox->Visible = save;

			_slave = slave;
			ExploreType = type;

			FillPathBox();
			GoToFolder(path);
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~ExplorerForm()
		{
			if (components)
			{
				delete components;
			}
		}

	protected: 


	private: System::Windows::Forms::ListView^  filesView;

	private: System::Windows::Forms::Button^  okButton;
	private: System::Windows::Forms::Button^  cancelButton;

	private: System::Windows::Forms::Button^  upButton;
	private: System::Windows::Forms::Button^  viewButton;
private: System::ComponentModel::IContainer^  components;


	protected: 


	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>


#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->components = (gcnew System::ComponentModel::Container());
			System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(ExplorerForm::typeid));
			this->filesView = (gcnew System::Windows::Forms::ListView());
			this->smallImageList = (gcnew System::Windows::Forms::ImageList(this->components));
			this->okButton = (gcnew System::Windows::Forms::Button());
			this->cancelButton = (gcnew System::Windows::Forms::Button());
			this->upButton = (gcnew System::Windows::Forms::Button());
			this->viewButton = (gcnew System::Windows::Forms::Button());
			this->saveBox = (gcnew System::Windows::Forms::TextBox());
			this->pathBox = (gcnew System::Windows::Forms::ComboBox());
			this->SuspendLayout();
			// 
			// filesView
			// 
			this->filesView->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom) 
				| System::Windows::Forms::AnchorStyles::Left) 
				| System::Windows::Forms::AnchorStyles::Right));
			this->filesView->FullRowSelect = true;
			this->filesView->Location = System::Drawing::Point(12, 38);
			this->filesView->Name = L"filesView";
			this->filesView->Size = System::Drawing::Size(541, 269);
			this->filesView->SmallImageList = this->smallImageList;
			this->filesView->TabIndex = 3;
			this->filesView->UseCompatibleStateImageBehavior = false;
			this->filesView->View = System::Windows::Forms::View::List;
			this->filesView->DoubleClick += gcnew System::EventHandler(this, &ExplorerForm::filesView_DoubleClick);
			this->filesView->SelectedIndexChanged += gcnew System::EventHandler(this, &ExplorerForm::filesView_SelectedIndexChanged);
			// 
			// smallImageList
			// 
			this->smallImageList->ImageStream = (cli::safe_cast<System::Windows::Forms::ImageListStreamer^  >(resources->GetObject(L"smallImageList.ImageStream")));
			this->smallImageList->TransparentColor = System::Drawing::Color::Fuchsia;
			this->smallImageList->Images->SetKeyName(0, L"XPfolder_closed.bmp");
			this->smallImageList->Images->SetKeyName(1, L"document.bmp");
			// 
			// okButton
			// 
			this->okButton->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Bottom | System::Windows::Forms::AnchorStyles::Right));
			this->okButton->Location = System::Drawing::Point(397, 313);
			this->okButton->Name = L"okButton";
			this->okButton->Size = System::Drawing::Size(75, 23);
			this->okButton->TabIndex = 4;
			this->okButton->Text = L"OK";
			this->okButton->UseVisualStyleBackColor = true;
			this->okButton->Click += gcnew System::EventHandler(this, &ExplorerForm::okButton_Click);
			// 
			// cancelButton
			// 
			this->cancelButton->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Bottom | System::Windows::Forms::AnchorStyles::Right));
			this->cancelButton->Location = System::Drawing::Point(478, 313);
			this->cancelButton->Name = L"cancelButton";
			this->cancelButton->Size = System::Drawing::Size(75, 23);
			this->cancelButton->TabIndex = 5;
			this->cancelButton->Text = L"Cancel";
			this->cancelButton->UseVisualStyleBackColor = true;
			this->cancelButton->Click += gcnew System::EventHandler(this, &ExplorerForm::cancelButton_Click);
			// 
			// upButton
			// 
			this->upButton->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->upButton->BackgroundImage = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"upButton.BackgroundImage")));
			this->upButton->BackgroundImageLayout = System::Windows::Forms::ImageLayout::Center;
			this->upButton->FlatStyle = System::Windows::Forms::FlatStyle::Popup;
			this->upButton->Location = System::Drawing::Point(495, 10);
			this->upButton->Name = L"upButton";
			this->upButton->Size = System::Drawing::Size(26, 23);
			this->upButton->TabIndex = 2;
			this->upButton->UseVisualStyleBackColor = true;
			this->upButton->Click += gcnew System::EventHandler(this, &ExplorerForm::upButton_Click);
			// 
			// viewButton
			// 
			this->viewButton->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->viewButton->BackgroundImage = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"viewButton.BackgroundImage")));
			this->viewButton->BackgroundImageLayout = System::Windows::Forms::ImageLayout::Center;
			this->viewButton->FlatStyle = System::Windows::Forms::FlatStyle::Popup;
			this->viewButton->Location = System::Drawing::Point(527, 10);
			this->viewButton->Name = L"viewButton";
			this->viewButton->Size = System::Drawing::Size(26, 23);
			this->viewButton->TabIndex = 6;
			this->viewButton->UseVisualStyleBackColor = true;
			// 
			// saveBox
			// 
			this->saveBox->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Bottom | System::Windows::Forms::AnchorStyles::Left) 
				| System::Windows::Forms::AnchorStyles::Right));
			this->saveBox->Location = System::Drawing::Point(12, 315);
			this->saveBox->Name = L"saveBox";
			this->saveBox->Size = System::Drawing::Size(379, 20);
			this->saveBox->TabIndex = 7;
			// 
			// pathBox
			// 
			this->pathBox->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left) 
				| System::Windows::Forms::AnchorStyles::Right));
			this->pathBox->FormattingEnabled = true;
			this->pathBox->Location = System::Drawing::Point(12, 10);
			this->pathBox->MaxLength = 2048;
			this->pathBox->Name = L"pathBox";
			this->pathBox->Size = System::Drawing::Size(477, 21);
			this->pathBox->TabIndex = 8;
			this->pathBox->SelectedIndexChanged += gcnew System::EventHandler(this, &ExplorerForm::pathBox_SelectedIndexChanged);
			this->pathBox->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &ExplorerForm::pathBox_KeyPress);
			// 
			// ExplorerForm
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(565, 348);
			this->Controls->Add(this->pathBox);
			this->Controls->Add(this->saveBox);
			this->Controls->Add(this->viewButton);
			this->Controls->Add(this->cancelButton);
			this->Controls->Add(this->okButton);
			this->Controls->Add(this->filesView);
			this->Controls->Add(this->upButton);
			this->MaximizeBox = false;
			this->MinimizeBox = false;
			this->Name = L"ExplorerForm";
			this->ShowIcon = false;
			this->ShowInTaskbar = false;
			this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
			this->Text = L"Select file(s)";
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
		private: System::Void cancelButton_Click(System::Object^  sender, System::EventArgs^  e) 
		{
			this->DialogResult = ::DialogResult::Cancel;
		}

		private: System::Void okButton_Click(System::Object^  sender, System::EventArgs^  e) 
		{
			this->DialogResult = ::DialogResult::OK;
		}

		private: System::Void filesView_DoubleClick(System::Object^  sender, System::EventArgs^  e) 
		{
			if (filesView->SelectedItems->Count < 1)
				return;

			if (filesView->SelectedItems[0]->ImageIndex == 0)
			{
				GoToFolder(Path + System::IO::Path::DirectorySeparatorChar + filesView->SelectedItems[0]->Text);
				return;
			}

			this->DialogResult = ::DialogResult::OK;
			Close();
		}

		private: System::Void upButton_Click(System::Object^  sender, System::EventArgs^  e) 
		{
			GoToFolder(Path + System::IO::Path::DirectorySeparatorChar + "..");
		}

		private: System::Void filesView_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
		{
			if (filesView->SelectedItems->Count < 1)
				return;

			if (saveBox->Visible && filesView->SelectedItems[0]->ImageIndex != 0)
			{
				saveBox->Text = filesView->SelectedItems[0]->Text;
			}
		}

		private: System::Void pathBox_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) 
		{
			if (e->KeyChar == '\r')
			{
				GoToFolder(pathBox->Text);
			}
		}

		private: System::Void pathBox_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
		{
			GoToFolder(pathBox->Text);
		}
};

}
